<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>防抖函数与节流函数</title>
	</head>
	<body>
		<div style="height:2000px"></div>
		
		<script>
			/**
			 * 函数防抖
			 * 定义：多次触发事件后，事件处理函数只执行一次，并且是在触发操作结束时执行
			 * 原理：对处理函数进行延时操作，若设定的延时到来之前，再次触发事件，则清除上一次的延时操作定时器，重新定时。
			 * 
			 * 最常见的就是用户注册时候的手机号码验证和邮箱验证了
			 **/
			/* let timer;
			window.onscroll  = function () {
				if(timer){
					clearTimeout(timer)
				}
				timer = setTimeout(function(){
					//滚动条位置
					let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
			　　 console.log('滚动条位置：' + scrollTop);
					timer = undefined;
				}, 200)
			} */
			/**
			 * 防抖函数封装 
			 **//*
			function debounce(method, delay){
				let timer = null;
				return function(){
					let that = this,
							args = arguments;
					timer && clearTimeout(timer);
					timer  = setTimeout(function(){
						method.apply(self,args);
					}, delay);
				}
			}
			window.onscroll = debounce(function(){
				let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
				console.log('滚动条位置：' + scrollTop);
			}, 200)
			*/
		</script>
		<script>
			/**
			 * 函数节流
			 * 定义：触发函数事件后，短时间间隔内无法连续调用，只有上一次函数执行后，过了规定的时间间隔，才能进行下一次的函数调用
			 * 
			 * 原理：对处理函数进行延时操作，若设定的延时到来之前，再次触发事件，则清除上一次的延时操作定时器，重新定时
			 * 
			 * 多数在监听页面元素滚动事件的时候会用到
			 **//*
			let startTime = Date.now(); //开始时间
			let time = 500; //间隔时间
			let timer;
			window.onscroll = function throttle(){
				let currentTime = Date.now();
				if(currentTime - startTime >= time){
					let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
					console.log('滚动条位置：' + scrollTop);
					startTime = currentTime;
				}else{
					clearTimeout(timer);
					timer = setTimeout(function () {
						throttle()
					}, 50);
				}
			}
			*/
			// 节流函数的封装
			/**
			 * 节流函数
			 * @param method 事件触发的操作
			 * @param mustRunDelay 间隔多少毫秒需要触发一次事件
			 */
			function throttle(method, mustRunDelay) {
				let timer,
						args = arguments,
						start;
				return function loop() {
					let that = this;
					let now = Date.now();
					if(!start){
						start = now;
					}
					if(timer){
						clearTimeout(timer);
					}
					if(now - start >= mustRunDelay){
						method.apply(that, args);
						start = now;
					}else {
						timer = setTimeout(function () {
							loop.apply(that, args);
						}, 50);
					}
				}
			}
			window.onscroll = throttle(function () {
				let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
				console.log('滚动条位置：' + scrollTop);
			},800)
			
		</script>
		
	</body>
</html>
